﻿/*******************************************************************************
 * AAEngine
 * Copyright (c) 2010 Mike Jarosch
 *
 * This file is licensed under the terms of the MIT license, which is included
 * in the "MIT License.txt" file at the root directory of this SDK.
 ******************************************************************************/

using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using AAEngine.Engine.Debug;

namespace AAEngine.Rendering2D
{
    public class RenderQueue
    {
        List<RenderInstance> _renderInstances = new List<RenderInstance>();

        public void DrawString(SpriteFont font, string text, Vector2 position, Color color)
        {
            DrawString(font, text, position, color, 0, Vector2.Zero, 1, SpriteEffects.None, 0);
        }

        public void DrawString(SpriteFont font, string text, Vector2 position, Color color, float rotation, Vector2 center, float scale, SpriteEffects effects, float layerDepth)
        {
            DrawString(font, text, position, color, rotation, center, new Vector2(scale), effects, layerDepth);
        }

        public void DrawString(SpriteFont font, string text, Vector2 position, Color color, float rotation, Vector2 center, Vector2 scale, SpriteEffects effects, float layerDepth)
        {
            RenderInstance ri = new RenderInstance()
            {
                Type = RenderInstanceType.Text,
                Font = font,
                Text = text,
                Position = position,
                Color = color,
                Rotation = rotation,
                Center = center,
                Scale = scale,
                Effects = effects,
                LayerDepth = layerDepth
            };

            _renderInstances.Add(ri);
        }

        public void AddRenderInstance(RenderInstance renderInstance)
        {
            _renderInstances.Add(renderInstance);
        }

        public void StartLayer()
        {
        }

        public void EndLayer()
        {
        }

        public SpriteBatch SpriteBatch { get; set; }
        public PrimitiveBatch PrimitiveBatch { get; set; }

        public void Render(GraphicsDevice graphicsDevice, Matrix camera)
        {
            Profiler.Enter("RenderQueue::Render");

            SpriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, null, null, null, null, camera);
            Profiler.Enter("RenderQueue::Rendering");
            foreach (var o in _renderInstances)
            {
                switch (o.Type)
                {
                    case RenderInstanceType.Text:
                        {
                            SpriteBatch.DrawString(o.Font, o.Text, o.Position, o.Color, o.Rotation, o.Center, o.Scale, o.Effects, o.LayerDepth);
                        }
                        break;
                    case RenderInstanceType.SpriteBatch:
                        {
                            if (o.Texture == null)
                            {
                                continue;
                            }
                            //Vector2 srcSize = new Vector2(o.SourceRectangle.Width, o.SourceRectangle.Height);
                            //Vector2 origin = o.Center;// *srcSize;

                            //Rectangle destinationRect = new Rectangle((int)o.Position.X, (int)o.Position.Y, o.Size.X, o.Size.Y);

                            SpriteEffects effects = SpriteEffects.None;
                            if (o.Scale.X < 0)
                            {
                                o.Scale = new Vector2(Math.Abs(o.Scale.X), o.Scale.Y);
                                effects |= SpriteEffects.FlipHorizontally;
                            }
                            if (o.Scale.Y < 0)
                            {
                                o.Scale = new Vector2(o.Scale.X, Math.Abs(o.Scale.Y));
                                effects |= SpriteEffects.FlipVertically;
                            }

                            SpriteBatch.Draw(o.Texture, o.Position, o.SourceRectangle, o.Color, MathHelper.ToRadians(o.Rotation), o.Center, o.Scale, effects, 0);
                        }
                        break;
                    case RenderInstanceType.LineList:
                        {
                            PrimitiveBatch.Begin(PrimitiveType.LineList, camera);

                            foreach (Vertex2D vpc in o.Vertices)
                            {
                                PrimitiveBatch.AddVertex(vpc.Position, vpc.Color);
                            }

                            PrimitiveBatch.End();
                        }
                        break;
                    case RenderInstanceType.TriangleList:
                        {
                            PrimitiveBatch.Begin(PrimitiveType.TriangleList, camera);

                            foreach (Vertex2D vpc in o.Vertices)
                            {
                                PrimitiveBatch.AddVertex(vpc.Position, vpc.Color);
                            }

                            PrimitiveBatch.End();
                        }
                        break;
                }
                //                spriteBatch.Draw(drawObject.Texture, new Rectangle((int)drawObject.Position.X, (int)drawObject.Position.Y, (int)drawObject.Size.X, (int)drawObject.Size.Y), Color.White);
            }
            Profiler.Exit("RenderQueue::Rendering");
            SpriteBatch.End();

            _renderInstances.Clear();

            Profiler.Exit("RenderQueue::Render");
        }
    }
}
